package soa.security.mgr.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.ldap.query.SearchScope;
import org.springframework.stereotype.Service;
import soa.security.Constants;
import soa.security.domain.*;
import soa.security.exception.OrganizationException;
import soa.security.mgr.service.AccountMgrService;
import soa.security.mgr.service.PersonMgrService;
import soa.security.mgr.service.RegisterMgrService;
import soa.security.util.BeanUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author CreGu
 * @date 2016/3/23
 */
@Service
@PropertySource(value = {"classpath:/ldap.properties"})
public class RegisterMgrServiceImpl extends BaseMgrServiceImpl implements RegisterMgrService {
    protected static final Logger log = LoggerFactory.getLogger(RegisterMgrServiceImpl.class);

    /**
     * ContextSourceTransactionManager 不具备事物传播性，所以这里service不能嵌入其他service
     */


    @Resource
    protected AccountMgrService accountMgrService;
    @Resource
    protected PersonMgrService personMgrService;

    /**
     * 公众单位机构id
     */
    @Value("#{ environment['publicOrg.orid'] }")
    private String pubOrid;

    /**
     * 公众个人机构id
     */
    @Value("#{ environment['publicOrg.peid'] }")
    private String pubPeid;

    @Override
    public Person addRegister(Account account, Person person) {
        String accountType = account.getAccountType();
        String orgId = null;

        try {
            if (Account.STAFF.equals(accountType)) {

            } else if (Account.PERSON.equals(accountType)) {
                orgId = pubPeid;
            } else if (Account.ORGANIZATION.equals(accountType)) {
                orgId = pubOrid;
            }

            if (StringUtils.isNotBlank(orgId)) {
                doRegister(orgId, account, person);

                person.setAccountId(account.getUid());
                return person;
            }
        } catch (OrganizationException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void doRegister(String organizationId, Account a, Person person)
            throws OrganizationException {
        try {
            validateOrganization(organizationId);

            if (StringUtils.isBlank(person.getUid())) {
                person.setUid("PE" + findMaxNumber(Person.class));
            }
            PersonMgrServiceImpl.validate(person);

            OrganizationUnit unit = gainOrganizationUnit(organizationId,
                    Constants.PERSON);

            person.setDn(person.buildDn(unit.getDn()));
            personDao.create(person);

            person.setOrId(organizationId);

            Organization or = findOrganization(organizationId);
            if (StringUtils.isBlank(a.getUid()))
                a.setUid(a.getBid() + "@"
                        + or.getEname());

            AccountMgrServiceImpl.validate(a);

            OrganizationUnit aunit = gainOrganizationUnit(organizationId,
                    Constants.ACCOUNT);

            a.setDn(a.buildDn(aunit.getDn()));
            a.setPersonBid(person.getUid());

            accountDao.create(a);
        } catch (Exception e) {
            wrapException(e);
        }
    }

    @Override
    public boolean addRealAuth(Person person) {
        // todo 暂不实现
        return true;
    }

    @Override
    public boolean certification(Person person2, Person person) {
        try {
            person2.setName(person.getName());
            person2.setMobile(person.getMobile());
            person2.setEmail(person.getEmail());

            person2.setIDNumber(person.getIDNumber());
            person2.setSocialSecurityCard(person.getSocialSecurityCard());

            BeanUtils.blank2Null(person2);
            boolean flag = doCert(person2);

            if (flag) {
                List<Account> accounts = doFindByPersonUid(person2.getOrId(), person2.getUid());
                if (accounts != null) {
                    for (Account a : accounts) {
                        String accountType = a.getAccountType();

                        if (Account.PERSON.equals(accountType)) {
                            a.setAccountStatus("3");
                        } else {
                            a.setAccountStatus("2");
                        }

                        a.setOldDn(a.getDn().toString());
                        BeanUtils.blank2Null(a);
                        accountDao.update(a);
                    }
                }

                personDao.update(person2);
                return true;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private List<Account> doFindByPersonUid(String organizationId, String personUid) {
        validateOrganization(organizationId);

        OrganizationUnit unit = gainOrganizationUnit(organizationId,
                Constants.ACCOUNT);

        return accountDao.allAccounts(unit.getDn().toString(),
                defaultSearchScope, personUid);
    }

    @Override
    public Applsystem bcReg(String appkey, String type) {
        Applsystem applsystem = null;
        if (StringUtils.isBlank(appkey)) {
            return null;
        }

        String ak = "e1NTSEF9N";

        List<Applsystem> aps = applsystemDao.findAllByAttr("ou=applsystem,bid=RE0000", SearchScope.SUBTREE, "appkey", appkey);

        if (aps != null && aps.size() > 0) {
            applsystem = aps.get(0);
        }

        if (applsystem != null) {
            String bcymUrl = applsystem.getBcymUrl();
            String bcymCond = applsystem.getBcymCond();

            if (StringUtils.isBlank(bcymUrl))
                return null;

            if ("0".equals(type) && StringUtils.isNotBlank(bcymCond) && bcymCond.equals(type)) {
                //已注册
                return applsystem;
            }

            if ("1".equals(type) && StringUtils.isNotBlank(bcymCond) && bcymCond.equals(type)) {
                //已实名
                return applsystem;
            }
        }

        return null;
    }

    @Override
    public boolean accountConfirm(String acid, String accountType) {
        String orgId;
        if (Account.PERSON.equals(accountType)) {
            orgId = pubPeid;
        } else {
            orgId = pubOrid;
        }

        try {
            Organization or = findOrganization(orgId);
            String uid = acid + "@" + or.getEname();

            return accountDao.findByUid(uid) == null;
        } catch (Exception e) {
            if (e instanceof EmptyResultDataAccessException)
                return true;
            else
                return false;
        }
    }

    private boolean doCert(Person person) {
        // todo 暂不实现
        return true;
    }
}
